"""
自己写的工具类
"""
import os
import random
import subprocess
import sys
import tempfile

from ffmpy3 import FFmpeg
import logging

log_level = logging.INFO  # INFO,DEBUG


def bsubprocess(cmd):
    """
    自定义的执行cmd命令的函数
    """
    try:
        with tempfile.TemporaryFile() as out_temp:
            # 获取临时文件的文件号
            fileno = out_temp.fileno()
            # 执行外部shell命令， 输出结果存入临时文件中
            p = subprocess.Popen(cmd, shell=True, stdout=fileno, stderr=fileno, stdin=subprocess.PIPE)
            p.communicate()
    except IOError as e:
        logging.debug(e)


class LogHandler(logging.Handler):
    """
    自定义的日志处理类
    """

    def __init__(self, handle, el):
        logging.Handler.__init__(self)
        self.handle = handle
        self.el = el

    def emit(self, msg):
        """
        捕获到日志输出时触发
        """
        print('捕获日志内容到ui')
        self.handle(self.el, msg)


class Logger:
    """
    自定义的日志类
    """
    FOREGROUND_WHITE = 0x0007
    FOREGROUND_BLUE = 0x01  # text color contains blue.
    FOREGROUND_GREEN = 0x02  # text color contains green.
    FOREGROUND_RED = 0x04  # text color contains red.
    FOREGROUND_YELLOW = FOREGROUND_RED | FOREGROUND_GREEN

    def __init__(self, clevel=logging.DEBUG):
        self.logger = logging.getLogger()
        self.logger.setLevel(log_level)
        fmt = logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S')
        # 设置CMD日志
        sh = logging.StreamHandler()
        sh.setFormatter(fmt)
        sh.setLevel(clevel)
        # 设置文件日志
        # fh = logging.FileHandler(path)
        # fh.setFormatter(fmt)
        # fh.setLevel(flevel)
        self.logger.addHandler(sh)
        # self.logger.addHandler(fh)

    def setlever(self, err):
        """
        设置输出日志的最低等级:
        DEBUG	最详细的日志信息，典型应用场景是 问题诊断
        INFO	信息详细程度仅次于 DEBUG ，通常只记录关键节点信息，用于确认一切都是按照我们预期的那样进行工作
        WARRING	当某些不期望的事情发生时记录的信息（如，磁盘可用空间较低），但此时应用程序还是正常运行的
        ERROR	由于一个更严重的问题导致某些功能不能正常运行时记录的信息
        CRITICAL	当发生严重错误，导致应用程序不能继续运行时记录的信息
        """
        if err == 'ERROR':
            self.logger.setLevel(logging.ERROR)
        if err == 'DEBUG':
            self.logger.setLevel(logging.DEBUG)
        if err == 'WARNING':
            self.logger.setLevel(logging.WARNING)
        if err == 'INFO':
            self.logger.setLevel(logging.INFO)

    def debug(self, message):
        """
        输出debug的日志信息
        """
        self.logger.debug(message)

    def info(self, message):
        """
        输出info的日志信息
        """
        self.logger.info(message)

    def war(self, message):
        """
        输出warning的日志信息
        """
        # set_color(color)
        self.logger.warning(message)
        # set_color(FOREGROUND_WHITE)

    def error(self, message):
        """
        输出error的日志信息
        """
        # set_color(color)
        self.logger.error(message)
        # set_color(FOREGROUND_WHITE)

    def cri(self, message):
        """
        输出critical的日志信息
        """
        self.logger.critical(message)


class FileTools:
    """
    个人日常使用的一些工具类
    """

    def __init__(self):
        self.logger = logging.getLogger('代码调试')
        self.logger.setLevel(logging.DEBUG)

    @staticmethod
    def listdir(path):
        """
        列出指定路径的目录下所有项
        :param path:指定的路径
        :return: 包含所有项的列表
        """
        try:
            return os.listdir(path)
        except IOError:
            print('目录不存在')

    @staticmethod
    def join(*args):
        """
        整合路径和文件
        :return: 包含文件名路径
        """
        return os.path.join(*args)

    @staticmethod
    def mkdir(paths):
        """
        创建目录
        :param paths: 指定的目录名,可以是多级目录
        """
        path_list = paths.split('/')
        for path in path_list:
            if not os.path.exists(path) and path != '':
                os.mkdir(path)
            os.chdir(path)

    @staticmethod
    def getpath(relative_path):
        """
        获得绝对的路径,即便是运行时的路径也能正确获得
        :param relative_path: 相对路径
        :return: 绝对路径
        """
        if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
            base_path = sys._MEIPASS
        else:
            base_path = os.path.abspath('.')
        return os.path.join(base_path, relative_path)

    @staticmethod
    def getworkdir():
        """
        获取工作目录
        :return: 工作目录
        """
        if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
            base_path = sys._MEIPASS
        else:
            base_path = os.path.abspath('.')
        return base_path

    @staticmethod
    def chdir(path):
        """
        切换目录
        :param path:指定的目录
        """
        os.chdir(path)

    @staticmethod
    def getcwd():
        """
        返回当前工作目录
        """
        return os.getcwd()

    @staticmethod
    def pardir():
        """
        返回上一级目录
        """
        return os.path.pardir

    @staticmethod
    def ganerate_random(length, _type):
        """
        生成随机数
        :length:随机数长度,一般是3 4 6 8 16
        :_type:随机数的种类:
            1是纯数字
            2是纯小写字母
            3是纯大写字母
            4是数字和小写字母混合
            5是数字和大写字母混合
        """
        list1 = [chr(x) for x in range(97, 123)]  # 小写
        list2 = [chr(x) for x in range(65, 91)]  # 大写
        list3 = [str(x) for x in range(0, 10)]  # 数字
        if _type == 1:
            return ''.join(random.sample(list3, length))

        if _type == 2:
            return ''.join(random.sample(list1, length))
        if _type == 3:
            return ''.join(random.sample(list2, length))
        if _type == 4:
            _list = list3+list1
            return ''.join(random.sample(_list, length))
        if _type == 5:
            _list = list3 + list2
            return ''.join(random.sample(_list, length))


class UrlTools:
    """
    关于url的一些工具集
    """

    def __init__(self):
        pass

    @staticmethod
    def getfilename(a):
        """
        获取url中的文件名
        :param a: 网页地址
        :return: 文件名
        """
        result = a.split('?')[0].split('/')[-1]
        return result


class MediaTools:
    """
    媒体处理的工具集
    """

    def __init__(self):
        self.fts = FileTools()

    def tomp4(self, inputs, outputs):
        """
        转换为mp4格式
        :param inputs:输入文件,多个文件可以字典形式传入
        :param outputs:输出文件,多个文件可以字典形式传入
        :return:
        """
        ffpath = self.fts.join(self.fts.getworkdir(), 'ffmpeg')
        print(inputs, outputs)
        ff = FFmpeg(executable=ffpath,
                    inputs={inputs: None},
                    outputs={outputs: None})
        print(ff.cmd)
        ff.run()

    @staticmethod
    def testcmd():
        cmd = 'ls -al'
        res = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        sout, serr = res.communicate()
        return res.returncode, sout, serr, res.pid


if __name__ == '__main__':
    fts = FileTools()
    print(fts.ganerate_random(6, 4))
